package com.epalmpay.service.order.impl;

import com.epalmpay.bean.ShopSettedBean;
import com.epalmpay.entity.Response;
import com.epalmpay.exception.ApplicationException;
import com.epalmpay.service.app.IAppNoticeService;
import com.epalmpay.service.member.IMemberService;
import com.epalmpay.service.posapi.PosApiService;
import com.epalmpay.status.Rescode;
import com.epalmpay.entity.*;
import com.epalmpay.enumdef.ActivityEnum.CouponCodeStatus;
import com.epalmpay.enumdef.ActivityEnum;
import com.epalmpay.enumdef.BizEnum;
import com.epalmpay.enumdef.BizEnum.MerchantSettedStatus;
import com.epalmpay.enumdef.BizEnum.MerchantSettedType;
import com.epalmpay.enumdef.BizEnum.ServiceOrderStatus;
import com.epalmpay.enumdef.CommonEnum;
import com.epalmpay.mapper.*;
import com.epalmpay.payplat.IPayAPI;
import com.epalmpay.payplat.PayBalanceChange;
import com.epalmpay.payplat.TkRefund;
import com.epalmpay.payplat.result.PayResult;
import com.epalmpay.payplat.result.RefundResult;
import com.epalmpay.service.order.IOrderService;
import com.epalmpay.service.weixin.IWalletService;
import com.epalmpay.util.*;
import com.epalmpay.util.payplat.DateUtils;
import com.epalmpay.util.payplat.UtilFun;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import com.epalmpay.dto.order.GoodCouponVerifyInDTO;
import com.epalmpay.dto.order.GoodCouponVerifyOutDTO;
import com.epalmpay.dto.order.OrderDetailOutDTO;
import com.epalmpay.dto.order.OrderInDTO;
import com.epalmpay.dto.order.OrderOutDTO;
import com.epalmpay.dto.system.BaseOutDTO;
import com.epalmpay.dto.system.TradeOfflineBaseOutDTO;
import com.epalmpay.service.management.ITemplateMailSendService;

import javax.annotation.Resource;

import java.math.BigDecimal;
import java.util.*;


@Service("orderService")
public class OrderServiceImpl implements IOrderService {

	protected Logger logger = Logger.getLogger(this.getClass());

	@Resource
	private OrderServiceGoodMapper orderServiceGoodMapper;
	@Resource
	private OrderServiceGoodDetailMapper orderServiceGoodDetailMapper;
	@Resource
	private MallGoodMapper mallGoodMapper;
	@Resource
	private MemberMapper memberMapper;
	@Resource
	private GroupMapper groupMapper;
	@Resource
	private ShopMapper shopMapper;
	@Resource
	private TradeOfflineMapper tradeOfflineMapper;
	@Resource
	private ShopGroupRelationMapper shopGroupRelationMapper;
	@Resource
	private OrderGoodItemMapper orderGoodItemMapper;
	@Resource
	private MallEntityGoodMapper mallEntityGoodMapper;

	@Autowired
	private RedpackageUserMapper redpackageUserMapper;

	@Resource(name="transactionManager")
	private DataSourceTransactionManager transactionManager;

	@Autowired
	private BonusSendLogMapper bonusSendLogMapper;

	@Resource
	private BonusVerifyLogMapper bonusVerifyLogMapper;
	@Resource
	private ShopUserMapper shopUserMapper;

	@Autowired
	private OrderGoodMapper orderGoodMapper;

	@Autowired
	private   MerchantSettedRecordMapper merchantSettedRecordMapper;

	@Resource
	@Lazy
	private ITemplateMailSendService templateMailSendService;

	@Resource
	private CouponUserMapper couponUserMapper;

	@Resource
	private IAppNoticeService appNoticeService;

	@Resource
	private IMemberService memberService;
	@Resource
	private PosApiService posApiService;

	@Resource
	private BonusVerifyShopMapper bonusVerifyShopMapper;


	@Resource
	private IWalletService walletService;
	
	public List<OrderOutDTO> getServiceGoodList(OrderInDTO orderInDTO,Page page) throws Exception{

		Map<String,Object> param=new HashMap<String,Object>();
		param.put("groupId", orderInDTO.getGroupId());
		param.put("shopId", orderInDTO.getLoginId());
		param.put("orderStatus", orderInDTO.getOrderStatus());
		param.put("startDate", orderInDTO.getStartDate());
		param.put("endDate", orderInDTO.getEndDate());
		param.put("name", orderInDTO.getName());

		List<OrderOutDTO> result = new ArrayList<OrderOutDTO>();

		int sumCount = orderServiceGoodMapper.selectServiceGoodListCount(param);
		page.setTotalResult(sumCount);
		if(sumCount<=0)
			return null;

		param.put("limit", page.getShowCount());
		param.put("start", page.getShowCount()*(page.getCurrentPage()-1));

		List<Map<String,Object>> serviceGoodList = orderServiceGoodMapper.selectServiceGoodList(param);

		for (Map<String, Object> serviceGood : serviceGoodList) {
			OrderOutDTO orderOutDTO = new OrderOutDTO();
			orderOutDTO.setId(Long.parseLong(serviceGood.get("id").toString()));
			if(serviceGood.get("order_no")!=null){
				orderOutDTO.setOrderNo(serviceGood.get("order_no").toString());
			}
			orderOutDTO.setMemberId(Long.parseLong(serviceGood.get("member_id")==null?"0":serviceGood.get("member_id").toString()));
			orderOutDTO.setMemberName(serviceGood.get("member_name")==null?"":serviceGood.get("member_name").toString());
			orderOutDTO.setGradeId(Long.parseLong(serviceGood.get("grade_id")==null?"0":serviceGood.get("grade_id").toString()));
			orderOutDTO.setGradeName(serviceGood.get("grade_name")==null?"":serviceGood.get("grade_name").toString());
			orderOutDTO.setGmtCreate((Date)serviceGood.get("gmt_create"));
			orderOutDTO.setGoodId(Long.parseLong(serviceGood.get("good_id")==null?"0":serviceGood.get("good_id").toString()));
			orderOutDTO.setGoodName(serviceGood.get("good_name")==null?"":serviceGood.get("good_name").toString());
			orderOutDTO.setNumber(Integer.parseInt(serviceGood.get("number")==null?"0":serviceGood.get("number").toString()));
			orderOutDTO.setUsedNumber(Integer.parseInt(serviceGood.get("used_number")==null?"0":serviceGood.get("used_number").toString()));
			orderOutDTO.setNoNumber(Integer.parseInt(serviceGood.get("number")==null?"0":serviceGood.get("number").toString())-Integer.parseInt(serviceGood.get("used_number")==null?"0":serviceGood.get("used_number").toString()));
			orderOutDTO.setOrderStatus(Integer.parseInt(serviceGood.get("order_status").toString()));

			result.add(orderOutDTO);
		}

		return result;
	}

	public OrderDetailOutDTO getServiceGoodDetail(OrderInDTO orderInDTO) throws Exception{
		OrderDetailOutDTO orderDetailOutDTO = new OrderDetailOutDTO();

		Map<String,Object> param=new HashMap<String,Object>();
		param.put("orderId", orderInDTO.getOrderId());
		param.put("shopId", orderInDTO.getUserId());

		//取得订单详情
		Map<String,Object> serviceGoodDetail = orderServiceGoodMapper.selectServiceGoodDetail(param);
		if(serviceGoodDetail != null){
			orderDetailOutDTO.setId((Long) serviceGoodDetail.get("id"));
			orderDetailOutDTO.setOrderNo((String)serviceGoodDetail.get("order_no"));
			orderDetailOutDTO.setMemberId((Long)serviceGoodDetail.get("member_id"));
			orderDetailOutDTO.setMemberName((String)serviceGoodDetail.get("member_name"));
			orderDetailOutDTO.setCardNo((String)serviceGoodDetail.get("card_no"));
			orderDetailOutDTO.setGradeId((Long)serviceGoodDetail.get("grade_id"));
			orderDetailOutDTO.setGradeName((String)serviceGoodDetail.get("grade_name"));
			orderDetailOutDTO.setPhone((String)serviceGoodDetail.get("phone"));
			orderDetailOutDTO.setFromType((Integer)serviceGoodDetail.get("from_type"));
			orderDetailOutDTO.setFromId((Long)serviceGoodDetail.get("from_id"));
			orderDetailOutDTO.setFromName((String)serviceGoodDetail.get("from_name"));
			orderDetailOutDTO.setGmtCreate((Date)serviceGoodDetail.get("gmt_create"));
			orderDetailOutDTO.setPayTime((Date)serviceGoodDetail.get("pay_time"));
			orderDetailOutDTO.setAllVerifyTime((Date)serviceGoodDetail.get("all_verify_time"));
			orderDetailOutDTO.setRemarkTime((Date)serviceGoodDetail.get("remark_time"));
			orderDetailOutDTO.setGoodId((Long)serviceGoodDetail.get("good_id"));
			orderDetailOutDTO.setGoodName((String)serviceGoodDetail.get("good_name"));
			String good_pic = (String)serviceGoodDetail.get("good_pic");
			if(!StringUtil.isEmpty(good_pic)) {
				String goodPicArr[] = good_pic.split(",");
				orderDetailOutDTO.setGoodPic(goodPicArr[0]);
			}
			//orderDetailOutDTO.setShopNum((Integer)serviceGoodDetail.get("shop_num"));
			orderDetailOutDTO.setShopNameList((String)serviceGoodDetail.get("shopname_list"));
			if((Long)serviceGoodDetail.get("good_id")==null){
				orderDetailOutDTO.setSalePrice((Integer)serviceGoodDetail.get("real_amount"));
				orderDetailOutDTO.setPromotionPrice((Integer)serviceGoodDetail.get("real_amount"));
			}else{
				orderDetailOutDTO.setSalePrice((Integer)serviceGoodDetail.get("sale_price"));
				orderDetailOutDTO.setPromotionPrice((Integer)serviceGoodDetail.get("promotion_price"));
				orderDetailOutDTO.setNoVipPrice((Integer)serviceGoodDetail.get("no_vip_price"));
				orderDetailOutDTO.setPromotionPrice((Integer)serviceGoodDetail.get("supply_price"));
			}
			orderDetailOutDTO.setOrderAmount((Integer)serviceGoodDetail.get("order_amount"));
			orderDetailOutDTO.setDiscountAmount((Integer)serviceGoodDetail.get("discount_amount"));
			orderDetailOutDTO.setRealAmount((Integer)serviceGoodDetail.get("real_amount"));
			orderDetailOutDTO.setNumber((Integer)serviceGoodDetail.get("number"));
			orderDetailOutDTO.setUsedNumber((Integer)serviceGoodDetail.get("used_number"));
			orderDetailOutDTO.setOrderStatus((Integer)serviceGoodDetail.get("order_status"));
		}
		//取得订单核销详情
		List<GoodCouponVerifyOutDTO> result = new ArrayList<GoodCouponVerifyOutDTO>();
		List<Map<String,Object>> goodCouponVerifyList = orderServiceGoodDetailMapper.selectGoodCouponVerifyListById(param);
		for (Map<String, Object> goodCouponVerify : goodCouponVerifyList) {
			GoodCouponVerifyOutDTO goodCouponVerifyOutDTO = new GoodCouponVerifyOutDTO();
			goodCouponVerifyOutDTO.setId((Long)goodCouponVerify.get("id"));
			goodCouponVerifyOutDTO.setVerifyTime((Date)goodCouponVerify.get("verify_time"));
			goodCouponVerifyOutDTO.setGoodId((Long)goodCouponVerify.get("good_id"));
			goodCouponVerifyOutDTO.setGoodName((String)goodCouponVerify.get("good_name"));
			goodCouponVerifyOutDTO.setCouponCode((String)goodCouponVerify.get("coupon_code"));
			goodCouponVerifyOutDTO.setOrderNo((String)goodCouponVerify.get("order_no"));
			goodCouponVerifyOutDTO.setCouponStatus((Integer)goodCouponVerify.get("coupon_status"));
			goodCouponVerifyOutDTO.setPrice((Integer)goodCouponVerify.get("price"));
			goodCouponVerifyOutDTO.setOriginalPrice((Integer)goodCouponVerify.get("original_price"));
			goodCouponVerifyOutDTO.setSettingPrice((Integer)goodCouponVerify.get("setting_price"));
			goodCouponVerifyOutDTO.setShopId((Long)goodCouponVerify.get("shop_id"));
			goodCouponVerifyOutDTO.setShopName((String)goodCouponVerify.get("shop_name"));
			goodCouponVerifyOutDTO.setPosId((Long)goodCouponVerify.get("pos_id"));
			goodCouponVerifyOutDTO.setPosName((String)goodCouponVerify.get("pos_name"));
			goodCouponVerifyOutDTO.setPosOperator((String)goodCouponVerify.get("pos_operator"));
			goodCouponVerifyOutDTO.setIsCorrect((Boolean)goodCouponVerify.get("is_correct"));
			if(goodCouponVerifyOutDTO.getIsCorrect()==Boolean.FALSE
					&& goodCouponVerifyOutDTO.getCouponStatus() == CouponCodeStatus.Verified.getType()){
				goodCouponVerifyOutDTO.setCanCorrect(Boolean.TRUE);
			}

			result.add(goodCouponVerifyOutDTO);
		}
		orderDetailOutDTO.setGoodCouponVerifyOutDTOList(result);

		return orderDetailOutDTO;
	}

	public TradeOfflineBaseOutDTO editConfirmRefundServiceGoodOrder(OrderInDTO orderInDTO) throws ApplicationException{


		//门店编号
		long shopid = 0L;
		Shop shop =null;
		String orderNo=orderInDTO.getOrderNo();//订单编号
		TradeOfflineBaseOutDTO baseOutDTO=new TradeOfflineBaseOutDTO();
		TradeOffline tradeOffline=tradeOfflineMapper.selectByOrderId(orderNo);
		Group group = groupMapper.selectByPrimaryKey(tradeOffline.getGroupId());
		if(tradeOffline==null){
			baseOutDTO.setErrorCode(Rescode.FAIL, "该订单不存在");
			return baseOutDTO;
		}

		if(orderInDTO.getMemberId()!=null&&!tradeOffline.getPayerId().equals(orderInDTO.getMemberId())){
			baseOutDTO.setErrorCode(Rescode.FAIL, "该订单付款信息不一致");
			return baseOutDTO;
		}

		int retreatAmountFee=0;
		if (orderNo.startsWith(Const.CONSUMPTION_VIRTUAL)) {//如果订单编号前缀为服务商品订单前缀，表明是服务商品的退款

			tradeOffline.setReceiverId(tradeOffline.getReceiverId());//收款者编号
			tradeOffline.setReceiverName(tradeOffline.getPayerName());//收款者姓名
//			tradeOffline.setPayerId(null);//付款者编号
			tradeOffline.setPayerName(group.getMerchantName());//付款者姓名
			
			//根据订单编号，查找到待使用的，订单表服务商品表信息
			OrderServiceGood orderServiceGood=orderServiceGoodMapper.selectOrderServiceGoodInfo(orderNo,BizEnum.ServiceOrderStatus.WaitingForUse.getType());

			if(orderServiceGood==null){
				baseOutDTO.setErrorCode(Rescode.FAIL, "该订单不存在");
				return baseOutDTO;
			}

			if(orderServiceGood.getUsedNumber()!=null&&orderServiceGood.getUsedNumber().equals(orderServiceGood.getNumber())){//使用数量不为空，且使用数量等于数量
				baseOutDTO.setErrorCode(Rescode.FAIL, "该订单卡劵已完成核销或使用");
				return baseOutDTO;
			}
			
			List<OrderServiceGoodDetail>  orderServiceGoodDetailList=orderServiceGoodDetailMapper.queryByOrderIdList(orderServiceGood.getId());
			if(orderServiceGoodDetailList.size()==0){
				baseOutDTO.setErrorCode(Rescode.FAIL, "该卡劵已全部核销");
				return baseOutDTO;
			}
			Integer total=orderServiceGoodDetailList.size();

			//可退订单金额= (购买优惠券数量/可使用数量)*订单总金额
			BigDecimal retreatAmount =new BigDecimal(orderServiceGood.getNumber()).divide(new BigDecimal(total))
					.multiply(new BigDecimal(tradeOffline.getOrderAmount()));

			//实际退款给用户数量=可退订单金额*退款比例
			retreatAmountFee=Tools.getRetirementAmount(tradeOffline.getOrderAmount(), tradeOffline.getRealAmount(), retreatAmount);
			if(orderServiceGood.getUsedNumber()==null||orderServiceGood.getUsedNumber()==0){
				orderServiceGood.setOrderStatus(ServiceOrderStatus.Refunding.getType());//已退款
			}else{
				orderServiceGood.setOrderStatus(ServiceOrderStatus.SectionRefund.getType());//部分退款
			}
			orderServiceGood.setRefundReason(orderInDTO.getRefundReason());
			orderServiceGood.setGmtModified(new Date());
			orderServiceGoodMapper.updateByPrimaryKeySelective(orderServiceGood);
			//更新 券码状态
			for (OrderServiceGoodDetail orderServiceGoodDetail : orderServiceGoodDetailList) {
				orderServiceGoodDetail.setCouponStatus(ActivityEnum.CouponCodeStatus.Refund.getType());
				orderServiceGoodDetail.setGmtModified(new Date());
				orderServiceGoodDetailMapper.updateByPrimaryKeySelective(orderServiceGoodDetail);
			}

		}
		else if (orderNo.startsWith(Const.CONSUMPTION_REAL)) {
			//如果订单编号为商城商品订单前缀，表明是商城商品退款

			OrderGood orderGood = orderGoodMapper.selectByOrderNo(orderNo);//根据订单编号查询订单表事物商品存在
			if(orderGood.getShopId() !=null){
				shopid=orderGood.getShopId();
				shop = shopMapper.selectByPrimaryKey(shopid);

			}

			if(orderGood!= null && orderGood.getUserRefund()==1){//是用于申请退款

			}else{
				baseOutDTO.setErrorCode(Rescode.FAIL, "未找到待审核的商品订单");
				return baseOutDTO;
			}
			retreatAmountFee=orderInDTO.getRefundAmount().multiply(new BigDecimal(100)).intValue();

			if(retreatAmountFee>tradeOffline.getRealAmount()){
				baseOutDTO.setErrorCode(Rescode.FAIL, "退款金额不能大于实付金额");
				return baseOutDTO;
			}

			orderGood.setRefundAmount(retreatAmountFee);
			orderGood.setUserRefund((byte)3);
			orderGood.setStatus(BizEnum.MallOrderStatus.Refunded.getType());
			orderGoodMapper.updateByPrimaryKeySelective(orderGood);


			List<OrderGoodItem> orderGoodItemList=orderGoodItemMapper.selectGoodIdByOrderNo(orderNo);
			for(OrderGoodItem orderGoodItem : orderGoodItemList) {
				Long goodId=orderGoodItem.getGoodId();
				Integer goodNum=orderGoodItem.getGoodNum();


				OrderGoodItem itemId=new OrderGoodItem();
				itemId.setId(orderGoodItem.getId());
				OrderGood orderStatus=orderGoodMapper.selectStatusByOrderGoodItemId(itemId);
				if(orderStatus!=null){
					//如果没有快递单号，即还未发货的退款，则不能减销量，只加库存，因为销量在发货后才增加
					if(Tools.isEmpty(orderStatus.getExpressNo())){
						int a=mallEntityGoodMapper.onlyAddStockNumberById(goodId, goodNum);
					}else{
						int a=mallEntityGoodMapper.addGoodStockNumberById(goodId, goodNum);//加库存，减销量
						/*if(orderStatus.getExpressNo().equals("-1")){
							//如果快递单号是-1，代表是商家自送，为了避免给微信端传值异常，对该订单的快递单号置空
							OrderGood orderGoodTemp=new OrderGood();
							orderGoodTemp.setId(orderStatus.getId());
							orderGoodTemp.setExpressNo(orderStatus.getExpressNo());
							orderGoodMapper.updateOrderExpressNoToNullById(orderGoodTemp);
						}*/
					}
				}

			}
			
			shopid = orderGood.getShopId();
		}else{
			baseOutDTO.setErrorCode(Rescode.FAIL, "该订单不能退款");
			return baseOutDTO;
		}
		//直接转化成int类型 小于1分钱 不做退款处理
		/*if(retreatAmountFee==0){
			baseOutDTO.setErrorCode(Rescode.FAIL, "实际可退款金额小于1分钱,无法发起退款");
			return baseOutDTO;
		}*/
		Member member=null;
		logger.info("===========退款实付金额retreatAmountFee=============="+retreatAmountFee);
		if(retreatAmountFee !=0){

			logger.info ("可退款给用户金额"+retreatAmountFee);
			 member=memberMapper.queryGroup(tradeOffline.getPayerId());
			if(tradeOffline.getPayType().equals((byte) BizEnum.PaymentType.Wallet.getType())){
//				  member =memberMapper.queryGroup(tradeOffline.getPayerId());
				PayResult payResult=walletService.updateUserLockedAmount(member.getVirtualCard(), member.getPayGroupCode(),
						member.getUserId(), retreatAmountFee+"", "0", 0,tradeOffline.getOrderId());
				tradeOffline.setTransOrderNo(payResult.getOrderId());

			}else if(tradeOffline.getPayType().equals((byte) BizEnum.PaymentType.WebChat.getType())){

				TkRefund tkRefund=TkRefund.initialize("WECHAT", tradeOffline.getMerchantNo(), tradeOffline.getOrderId(), retreatAmountFee+"",
						tradeOffline.getRealAmount()+"", tradeOffline.getTerminalNo());
				RefundResult payResult=IPayAPI.finishTkRefund(tkRefund);
				if (!payResult.getResult_code().equals("000000")) {
					throw new ApplicationException(Rescode.FAIL, "微信调用失败" + payResult.getResult_msg());
				}
				tradeOffline.setTransOrderNo(payResult.getRefund_order_no());
			}
		}

		tradeOffline.setTransactionStatus((byte) BizEnum.TransactionStatus.ISRefund.getType());
		tradeOfflineMapper.updateByPrimaryKeySelective(tradeOffline);

		//退款成功后生成一条新的记录
		TradeOffline tradeOffline1 = new TradeOffline();
		tradeOffline1.setGmtCreate(new Date());
		tradeOffline1.setGmtModified(new Date());
		tradeOffline1.setGroupId(tradeOffline.getGroupId());
		tradeOffline1.setOrderId(UtilFun.createOrderNum());
		if( shopid !=0){
			tradeOffline1.setPayerId(shopid);
			if(shop !=null){
				tradeOffline1.setPayerName(shop.getMerchantName());
				tradeOffline1.setPayerType((byte) CommonEnum.UserType.Store.getType());
			}
		}else{
			tradeOffline1.setPayerId(tradeOffline.getGroupId());
			tradeOffline1.setPayerName(group.getMerchantName());
			tradeOffline1.setPayerType((byte) CommonEnum.UserType.BusinessManager.getType());
		}
		Member member1 = memberMapper.selectByPrimaryKey(tradeOffline.getPayerId());
		tradeOffline1.setReceiverId(tradeOffline.getPayerId().toString());
		tradeOffline1.setReceiverName(member1.getName());
		tradeOffline1.setTransactionType((byte)BizEnum.TransactionType.Refund.getType());
		tradeOffline1.setTransactionStatus((byte)BizEnum.TransactionStatus.Refund.getType());
		tradeOffline1.setOrderAmount(-1*tradeOffline.getOrderAmount());
		if(tradeOffline.getRealAmount() !=0){
			tradeOffline1.setRealAmount(-1*tradeOffline.getRealAmount());
		}else{
			tradeOffline1.setRealAmount(0);
		}
		tradeOffline1.setPayType(tradeOffline.getPayType());
		tradeOffline1.setMemo("退款成功记录");
		if(tradeOffline.getDiscountAmount() !=null){
            tradeOffline1.setDiscountAmount(-1*tradeOffline.getDiscountAmount());
        }
        if(tradeOffline.getBonusValue() !=null){
            tradeOffline1.setBonusValue(-1*tradeOffline.getBonusValue());
        }

		tradeOfflineMapper.insertSelective(tradeOffline1);

		//其他退回
		logger.info("---------------------------------------其他退回--------------------------------");
		posApiService.refundBenefit(tradeOffline,UtilFun.createOrderNum());

		//退款成功 更新会员的消费总额跟消费次数
		memberService.updateStatisMemberInfo(member.getId(),tradeOffline.getRealAmount());

		BonusVerifyLog bonusVerifyLog =bonusVerifyLogMapper.queryBonusVerifyLogByTradeId(tradeOffline.getId());

		if(bonusVerifyLog !=null){
			bonusVerifyLog.setAdjustStatus(ActivityEnum.BonusVerityStatus.TradeCancel.getType());
			bonusVerifyLogMapper.updateByPrimaryKeySelective(bonusVerifyLog);
			//使用了积分退回给用户
			memberMapper.updateMemberBonusById(tradeOffline.getPayerId(), bonusVerifyLog.getAdjustAmount());
			//门店积分退回
			if(bonusVerifyLog.getShopId() !=null){
				bonusVerifyShopMapper.updateShopBonusInfo(bonusVerifyLog.getShopId(),bonusVerifyLog.getSettingAmount());
			}
		}



		if(shopid != 0) {//如果是商户商品，则进行推送
			//获取商户账号
			Userbase userbase = shopMapper.getUserNameByShopId(shopid);
			//发送退款推送信息
			Notice notice = new Notice();
			try {
				notice.setNoticetype(0);
				notice.setSender(tradeOffline.getGroupId());
				notice.setReceiver(userbase.getUsername());
				notice.setNoticetitle("您有一笔退款申请");
				notice.setNoticetarget("ACCOUNT");
				notice.setNoticebody("您有一笔退款申请");
				notice.setGroupid(tradeOffline.getGroupId());
				notice.setNoticestatus(1);
				notice.setIsplay(0);
				notice.setType(1);
				notice.setTvalue("");
				appNoticeService.sendNoticeToUsers(notice);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		baseOutDTO.setTradeOffline(tradeOffline);
		baseOutDTO.setErrorCode(Rescode.SUCCESS, "退款成功");
		
		return baseOutDTO;
	}  






	public void editCloseOrderServiceGoodOrder(OrderInDTO orderInDTO) throws Exception{
		OrderServiceGood record = new OrderServiceGood();
		record.setId(orderInDTO.getOrderId());
		record.setOrderStatus(ServiceOrderStatus.Closed.getType());
		record.setGmtModified(new Date());
		orderServiceGoodMapper.updateByPrimaryKeySelective(record);
	}

	public List<GoodCouponVerifyOutDTO> getGoodCouponVerifyList(GoodCouponVerifyInDTO goodCouponVerifyInDTO,Page page) throws Exception{

		Map<String,Object> param=new HashMap<String,Object>();
		param.put("groupId", goodCouponVerifyInDTO.getGroupId());
		param.put("couponCodeStatus", goodCouponVerifyInDTO.getCouponCodeStatus());
		param.put("startDate", goodCouponVerifyInDTO.getStartDate());
		param.put("endDate", goodCouponVerifyInDTO.getEndDate());
		param.put("name", goodCouponVerifyInDTO.getName());
		param.put("shopId", goodCouponVerifyInDTO.getShopId());

		List<GoodCouponVerifyOutDTO> result = new ArrayList<GoodCouponVerifyOutDTO>();

		int sumCount = orderServiceGoodDetailMapper.selectGoodCouponVerifyListCount(param);
		page.setTotalResult(sumCount);
		if(sumCount<=0)
			return null;

		param.put("limit", page.getShowCount());
		param.put("start", page.getShowCount()*(page.getCurrentPage()-1));

		List<Map<String,Object>> goodCouponVerifyList = orderServiceGoodDetailMapper.selectGoodCouponVerifyList(param);

		for (Map<String, Object> goodCouponVerify : goodCouponVerifyList) {
			GoodCouponVerifyOutDTO goodCouponVerifyOutDTO = new GoodCouponVerifyOutDTO();
			goodCouponVerifyOutDTO.setId((Long)goodCouponVerify.get("id"));
			goodCouponVerifyOutDTO.setVerifyTime((Date)goodCouponVerify.get("verify_time"));
			goodCouponVerifyOutDTO.setGoodId((Long)goodCouponVerify.get("good_id"));
			goodCouponVerifyOutDTO.setGoodName((String)goodCouponVerify.get("good_name"));
			goodCouponVerifyOutDTO.setCouponCode((String)goodCouponVerify.get("coupon_code"));
			goodCouponVerifyOutDTO.setOrderNo((String)goodCouponVerify.get("order_no"));
			goodCouponVerifyOutDTO.setCouponStatus((Integer)goodCouponVerify.get("coupon_status"));
			goodCouponVerifyOutDTO.setPrice((Integer)goodCouponVerify.get("price"));
			goodCouponVerifyOutDTO.setOriginalPrice((Integer)goodCouponVerify.get("original_price"));
			goodCouponVerifyOutDTO.setSettingPrice((Integer)goodCouponVerify.get("setting_price"));
			goodCouponVerifyOutDTO.setShopId((Long)goodCouponVerify.get("shop_id"));
			goodCouponVerifyOutDTO.setShopName((String)goodCouponVerify.get("shop_name"));
			goodCouponVerifyOutDTO.setPosId((Long)goodCouponVerify.get("pos_id"));
			goodCouponVerifyOutDTO.setPosName((String)goodCouponVerify.get("pos_name"));
			goodCouponVerifyOutDTO.setPosOperator((String)goodCouponVerify.get("pos_operator"));
			goodCouponVerifyOutDTO.setIsCorrect((Boolean)goodCouponVerify.get("is_correct"));
			if(goodCouponVerifyOutDTO.getIsCorrect()==Boolean.FALSE
					&& goodCouponVerifyOutDTO.getCouponStatus() == CouponCodeStatus.Verified.getType()){
				goodCouponVerifyOutDTO.setCanCorrect(Boolean.TRUE);
			}

			result.add(goodCouponVerifyOutDTO);
		}

		return result;
	}

	//核销冲正
	@Override
	public int editGoodCouponVerifyCorrect(GoodCouponVerifyInDTO goodCouponVerifyInDTO) throws Exception{
		int result = 0;
		OrderServiceGoodDetail record = new OrderServiceGoodDetail();
		OrderServiceGoodDetail oldRecord = orderServiceGoodDetailMapper.selectByPrimaryKey(goodCouponVerifyInDTO.getId());
		//减30分钟
		Date date = new Date();
		date.setTime(date.getTime() - 30*60*1000);
		if(oldRecord.getVerifyTime()!=null && oldRecord.getVerifyTime().before(date)) {
			return -1;
		}
		record.setId(goodCouponVerifyInDTO.getId());
		record.setCouponStatus(CouponCodeStatus.Washed.getType());
		record.setIsCorrect(Boolean.TRUE);
		record.setGmtModified(new Date());
		record.setShopId(null);
		record.setPosId(null);
		record.setPosName(null);
		record.setPosOperator(null);

		OrderServiceGood orderServiceGood = orderServiceGoodMapper.selectByPrimaryKey(oldRecord.getOrderId());

		if(!orderServiceGood.getOrderNo().contains("TICK")){
			if(orderServiceGood.getOrderStatus() == ServiceOrderStatus.OrderFinished.getType()) {
				throw new ApplicationException("订单已经完成，不能冲正!");
			}

//			if(orderServiceGood.getNumber().equals(orderServiceGood.getUsedNumber())) {
				orderServiceGood.setAllVerifyTime(null);
				orderServiceGood.setOrderStatus(ServiceOrderStatus.WaitingForUse.getType());


				orderServiceGood.setUsedNumber((short) (orderServiceGood.getUsedNumber() - 1));
//				orderServiceGood.setUsedNumber((short)0);
				orderServiceGoodMapper.updateByPrimaryKey(orderServiceGood);


//				orderServiceGoodMapper.updateVerifyNumberById(oldRecord.getOrderId(), -1);
//			}

		}else{//门票逻辑
			orderServiceGood.setAllVerifyTime(null);
			orderServiceGood.setOrderStatus(ServiceOrderStatus.WaitingForUse.getType());

			orderServiceGood.setUsedNumber((short)0);
			orderServiceGoodMapper.updateByPrimaryKey(orderServiceGood);
		}


		result = orderServiceGoodDetailMapper.updateCouponVerifyCorrectByPrimaryKey(record);

		return result;
	}

	//商品券核销
	public int editGoodCouponVerify(GoodCouponVerifyInDTO goodCouponVerifyInDTO,String rootHomeUrl) throws Exception{
		int result = 0;

		Date date = new Date();
		OrderServiceGoodDetail oldDetail = orderServiceGoodDetailMapper.selectByPrimaryKey(goodCouponVerifyInDTO.getId());

		//更新核销状态
		OrderServiceGoodDetail record = new OrderServiceGoodDetail();
		record.setId(goodCouponVerifyInDTO.getId());
		record.setCouponStatus(CouponCodeStatus.Verified.getType());
		record.setShopId(goodCouponVerifyInDTO.getShopId());
		record.setVerifyTime(date);
		record.setGmtModified(date);

		result = orderServiceGoodDetailMapper.updateByPrimaryKeySelective(record);
		OrderServiceGood order = orderServiceGoodMapper.selectByPrimaryKey(oldDetail.getOrderId());
		order.setUsedNumber(order.getUsedNumber()==null?0:order.getUsedNumber());

		//更新总记录
		OrderServiceGood orderUpdate = new OrderServiceGood();
		orderUpdate.setId(order.getId());
		orderUpdate.setUsedNumber(Integer.valueOf(order.getUsedNumber() + 1).shortValue());
		if(orderUpdate.getUsedNumber() == order.getNumber()){
			orderUpdate.setAllVerifyTime(date);
			orderUpdate.setOrderStatus(BizEnum.ServiceOrderStatus.Verified.getType());
		}
		orderUpdate.setGmtModified(date);
		orderServiceGoodMapper.updateByPrimaryKeySelective(orderUpdate);

		try {
			templateMailSendService.sendCouponVerifyTemplate(goodCouponVerifyInDTO.getShopId(), order.getMemberId(), oldDetail.getCouponCode(), order.getGoodName(),
					BizEnum.WebTemplateType.template8.getType(),order.getOrderNo(),rootHomeUrl);
		} catch (Exception e) {
			logger.info ("模板消息发送失败"+e);
		}
		return result;
	}

	public OrderDetailOutDTO  SearchOrderByCouponCode(GoodCouponVerifyInDTO goodCouponVerifyInDTO) throws Exception{
		OrderDetailOutDTO result = new OrderDetailOutDTO();
		OrderServiceGoodDetail record = orderServiceGoodDetailMapper.selectByCouponCode(goodCouponVerifyInDTO.getCouponCode(),goodCouponVerifyInDTO.getGroupId(), goodCouponVerifyInDTO.getShopId());
		if(record == null)
			throw new ApplicationException(Rescode.FAIL,"券码不存在！");
		if(record.getIsCorrect()==Boolean.TRUE
				&& record.getCouponStatus() == CouponCodeStatus.Verified.getType()){
			throw new ApplicationException(Rescode.FAIL,"券码已经冲正并核销，不能再继续操作！");
		}

		//查询订单明细
		OrderInDTO orderInDTO = new OrderInDTO();
		orderInDTO.setOrderId(record.getOrderId());
		orderInDTO.setUserId(goodCouponVerifyInDTO.getShopId());
		result = getServiceGoodDetail(orderInDTO);
		result.setOrderId(record.getOrderId());
		result.setCouponCodeId(record.getId());//取得券码表id
		result.setCouponCodeStatus(record.getCouponStatus());//取当前券码状态
		result.setIsCorrect(record.getIsCorrect());
		if(record.getIsCorrect()==Boolean.FALSE
				&& record.getCouponStatus() == CouponCodeStatus.Verified.getType()){
			result.setCanCorrect(Boolean.TRUE);
		}
		//取得券码可核销门店列表
		result.setShopList(mallGoodMapper.selectCanVerifyShopListByCouponCode(goodCouponVerifyInDTO.getCouponCode(),goodCouponVerifyInDTO.getGroupId()));

		return result;
	}


	//服务商品券核销日打款(格式yyyymmdd)
	public int serviceGoodVerifyOutMontyDay(Date statisDate) throws Exception{
		int result = 0;

		List<ShopSettedBean> shopList = orderServiceGoodDetailMapper.selectCouponVerifySettingShopList(statisDate);
		if(shopList == null)
			return result;

		for(ShopSettedBean shop:shopList){
			result = CouponVerifyShopOutMoney(shop,statisDate);
			//推送消息
			if(shop.getShopId() != 0) {//如果是商户商品，则进行推送
				//获取商户账号
				Userbase userbase = shopMapper.getUserNameByShopId(shop.getShopId());
				//发送退款推送信息
				Notice notice = new Notice();
				try {
					notice.setNoticetype(0);
					notice.setSender(shop.getGroupId());
					notice.setReceiver(userbase.getUsername());
					notice.setNoticetitle("您有一笔款项到账了");
					notice.setNoticetarget("ACCOUNT");
					notice.setNoticebody("您有一笔款项到账了");
					notice.setGroupid(shop.getGroupId());
					notice.setNoticestatus(1);
					notice.setIsplay(0);
					notice.setType(1);
					notice.setTvalue("");
					appNoticeService.sendNoticeToUsers(notice);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}

		return result;
	}

	//服务商品券码核销门店结算出款
	public int CouponVerifyShopOutMoney(ShopSettedBean settingShop,Date statisDate) throws Exception{
		int result = 0;
		if(settingShop == null)
			return 0;

		settingShop.setSettingPrice(settingShop.getSettingPrice()==null?0:settingShop.getSettingPrice());
		if(settingShop.getSettingPrice() <= 0)
			return 0;


		StringBuffer sb = new StringBuffer();
		Shop shop = shopMapper.selectByPrimaryKey(settingShop.getShopId());
		Group group = groupMapper.selectByPrimaryKey(settingShop.getGroupId());
		ShopGroupRelation shopGroupRelation = shopGroupRelationMapper.selectShopInfo(group.getId(),shop.getId());
		if(shopGroupRelation == null)
			return 0;
		//将门店结算插入结算记录
		String OrgOrderNum = UtilFun.createOrderNum();
		MerchantSettedRecord record =merchantSettedRecordMapper.selectByShop(settingShop.getShopId(),settingShop.getGroupId(),MerchantSettedType.serviceGoodsSetted.getType(),DateUtils.getDateTimeString("yyyy-MM-dd", statisDate));
		if(record!=null){
			if(record.getStatus().intValue()==MerchantSettedStatus.merchantSetted.getType()){
				throw new Exception("该商户已经结算 请手动调整");
			}
		}else{
			record =new MerchantSettedRecord();
		}
		record.setAmount(settingShop.getSettingPrice());
		record.setGroupId(settingShop.getGroupId());
		String amountDes=SysUtils.string2MD5(record.getAmount() + SysUtils.formatString(settingShop.getShopId(), 7));
		record.setAmountDes(amountDes);
		record.setGmtCreate(new Date());
		record.setGmtModified(new Date());
		record.setLastOrderNum(OrgOrderNum);
		record.setOutOrderNum(OrgOrderNum);
		record.setShopId(settingShop.getShopId());
		record.setStaticDate(statisDate);
		record.setStatus(MerchantSettedStatus.merchantUnSetted.getType());
		record.setType(MerchantSettedType.serviceGoodsSetted.getType());
		if(record.getId()!=null&&record.getId()>0){
			merchantSettedRecordMapper.updateByPrimaryKey(record);
		}else{

			merchantSettedRecordMapper.insert(record);
		}
		result = orderServiceGoodDetailMapper.updateShopSettingInfo(record.getId(),null,settingShop.getDetailIds());

		PayBalanceChange payBalanceChange = PayBalanceChange.initialize(group.getPayGroupCode(),
				shopGroupRelation.getPayMerchantCode(),settingShop.getSettingPrice().toString(), "1",
				OrgOrderNum, DateUtils.getDateTimeString("yyyyMMddHHmmss"), StringUtil.getRandNumberStr(10), "156");
		PayResult payResult = IPayAPI.consumptionBalanceChangeMerchant(payBalanceChange);
		if(payResult==null||!payResult.getRespCode().equals("0000")) {
			logger.error(sb.append("商家:" + shop.getMerchantName() + "(" + settingShop.getShopId() + ")"  + "打款失败!"));
			String newOrgOrderNum = UtilFun.createOrderNum();
			record.setOutOrderNum(newOrgOrderNum);
			record.setStatus(MerchantSettedStatus.merchantSettedFail.getType());
			merchantSettedRecordMapper.updateByPrimaryKey(record);
			return -1;
		}

		try {
			//交易记录创建
			TradeOffline tradeOffline = new TradeOffline();
			tradeOffline.setGmtCreate(new Date());
			tradeOffline.setGroupId(group.getId());
			tradeOffline.setOrderId(OrgOrderNum);
			tradeOffline.setPayerId(group.getId());
			tradeOffline.setPayerName(group.getMerchantName());
			tradeOffline.setPayerType((byte) CommonEnum.UserType.BusinessManager.getType());
			tradeOffline.setReceiverId(shop.getId().toString());
			tradeOffline.setReceiverName(shop.getMerchantName());
			tradeOffline.setReceiverType((byte) CommonEnum.UserType.Store.getType());
			tradeOffline.setTransactionType((byte)  BizEnum.TransactionType.AddBalanceMerchant.getType());
			tradeOffline.setSubType((byte) BizEnum.PaymentScene.Online.getType());
			tradeOffline.setOrderAmount(settingShop.getSettingPrice());
			tradeOffline.setIsWallet(true);
			tradeOffline.setRealAmount(settingShop.getSettingPrice());
			tradeOffline.setPayType((byte) BizEnum.PaymentType.Wallet.getType());
			tradeOffline.setTransactionStatus((byte) BizEnum.TransactionStatus.Success.getType());
			tradeOffline.setTransOrderNo(payResult.getOrderId());
			tradeOffline.setPayOrderid(payBalanceChange.getOrgOrderNum());
			tradeOffline.setMemo("服务商品结算");
			result = tradeOfflineMapper.insertSelective(tradeOffline);


			//更新订单明细状态
			record.setLastOrderNum(payBalanceChange.getOrgOrderNum());
			record.setSuccessOrderId(tradeOffline.getId());
			record.setStatus(BizEnum.MerchantSettedStatus.merchantSetted.getType());
			merchantSettedRecordMapper.updateByPrimaryKey(record);
			result = orderServiceGoodDetailMapper.updateShopSettingInfo(null,tradeOffline.getId(),settingShop.getDetailIds());

		}catch (Exception e) {
			logger.error("commit error", e);
			e.printStackTrace();
			throw e;
		}
		return 1;
	}

	@Override
	public int finishCouponMerchantSetted(Date statisDate) throws Exception {
		int result = 0;

		List<ShopSettedBean> shopList = couponUserMapper.selectCouponUserShopList(statisDate);
		if(shopList == null)
			return result;

		for(ShopSettedBean shop:shopList){
			result = couponShopOutMoney(shop,statisDate);
		}

		return result;

	}
	/**
	 * 结算门店的实物商品
	 * @param statisDate
	 * @return
	 * @throws Exception
	 */
	@Override
	public int finishGoodsMerchantSetted(Date statisDate) throws Exception {
		int result = 0;

		List<ShopSettedBean> shopList = orderGoodItemMapper.selectFinishOrderSettingShopList(statisDate);
		if(shopList == null)
			return result;

		for(ShopSettedBean shop:shopList){
			result = goodsShopOutMoney(shop,statisDate);
		}

		return result;

	}



	@Override
	public List<Map> selectServiceGoodByMonth(Map map) {
		return orderServiceGoodDetailMapper.selectServiceGoodByMonth(map);
	}

	@Override
	public List<Map> selectServiceGoodByDay(Map map) {
		return orderServiceGoodDetailMapper.selectServiceGoodByDayList(map);
	}

	@Override
	public List<Map> selectServiceGoodByMonthList(Map map) {
		return orderServiceGoodDetailMapper.selectServiceGoodByMonthList(map);
	}

	@Override
	public List<Map> selectServiceGoodByDayList(Map map) {
		return orderServiceGoodDetailMapper.selectServiceGoodByDayList(map);
	}

	@Override
	public OrderServiceGoodDetail getServiceGoodDetailByCode(Map param) throws Exception {
		return orderServiceGoodDetailMapper.selectByCouponCode(param.get("couponCode").toString(), Long.parseLong(param.get("groupId").toString()), null);
	}


	//优惠券核销门店结算出款
	public int couponShopOutMoney(ShopSettedBean settingShop,Date statisDate) throws Exception{
		if(settingShop == null)
			return 0;

		settingShop.setSettingPrice(settingShop.getSettingPrice()==null?0:settingShop.getSettingPrice());
		if(settingShop.getSettingPrice() <= 0)
			return 0;
		//将门店结算插入结算记录
		String OrgOrderNum = UtilFun.createOrderNum();
		MerchantSettedRecord record =merchantSettedRecordMapper.selectByShop(settingShop.getShopId(),settingShop.getGroupId(),MerchantSettedType.couperSetted.getType(),DateUtils.getDateTimeString("yyyy-MM-dd", statisDate));
		if(record!=null){
			if(record.getStatus().intValue()==MerchantSettedStatus.merchantSetted.getType()){
				throw new Exception("该商户已经结算 请手动调整");
			}
		}else{
			record =new MerchantSettedRecord();
		}
		record.setAmount(settingShop.getSettingPrice());
		record.setGroupId(settingShop.getGroupId());
		String amountDes=SysUtils.string2MD5(record.getAmount() + SysUtils.formatString(settingShop.getShopId(), 7));
		record.setAmountDes(amountDes);
		record.setGmtCreate(new Date());
		record.setGmtModified(new Date());
		record.setLastOrderNum(OrgOrderNum);
		record.setOutOrderNum(OrgOrderNum);
		record.setShopId(settingShop.getShopId());
		record.setStaticDate(statisDate);
		record.setStatus(MerchantSettedStatus.merchantUnSetted.getType());
		record.setType(MerchantSettedType.couperSetted.getType());
		if(record.getId()!=null&&record.getId()>0){
			merchantSettedRecordMapper.updateByPrimaryKey(record);
		}else{
			merchantSettedRecordMapper.insert(record);
		}

		couponUserMapper.updateShopSettingInfo(record.getId(),null,settingShop.getDetailIds());

		StringBuffer sb = new StringBuffer();
		Shop shop = shopMapper.selectByPrimaryKey(settingShop.getShopId());
		Group group = groupMapper.selectByPrimaryKey(settingShop.getGroupId());
		ShopGroupRelation shopGroupRelation = shopGroupRelationMapper.selectShopInfo(group.getId(),shop.getId());



		PayBalanceChange payBalanceChange = PayBalanceChange.initialize(group.getPayGroupCode(),
				shopGroupRelation.getPayMerchantCode(),settingShop.getSettingPrice().toString(), "1",
				OrgOrderNum, DateUtils.getDateTimeString("yyyyMMddHHmmss"), StringUtil.getRandNumberStr(10), "156");
		PayResult payResult = IPayAPI.consumptionBalanceChangeMerchant(payBalanceChange);
		if(payResult==null||!payResult.getRespCode().equals("0000")) {
			String newOrgOrderNum = UtilFun.createOrderNum();
			record.setOutOrderNum(newOrgOrderNum);
			record.setStatus(MerchantSettedStatus.merchantSettedFail.getType());
			merchantSettedRecordMapper.updateByPrimaryKey(record);

			logger.error(sb.append("商家:" + shop.getMerchantName() + "(" + settingShop.getShopId() + ")"  + "打款失败!"));
			return -1;
		}

		try {
			//交易记录创建
			TradeOffline tradeOffline = new TradeOffline();
			tradeOffline.setGmtCreate(new Date());
			tradeOffline.setGroupId(group.getId());
			tradeOffline.setOrderId(OrgOrderNum);
			tradeOffline.setPayerId(group.getId());
			tradeOffline.setPayerName(group.getMerchantName());
			tradeOffline.setPayerType((byte) CommonEnum.UserType.BusinessManager.getType());
			tradeOffline.setReceiverId(shop.getId().toString());
			tradeOffline.setReceiverName(shop.getMerchantName());
			tradeOffline.setReceiverType((byte) CommonEnum.UserType.Store.getType());
			tradeOffline.setTransactionType((byte) BizEnum.TransactionType.AddBalanceMerchant.getType());
			tradeOffline.setOrderAmount(settingShop.getSettingPrice());
			tradeOffline.setRealAmount(settingShop.getSettingPrice());
			tradeOffline.setSubType((byte) BizEnum.PaymentScene.Online.getType());
			tradeOffline.setIsWallet(true);
			tradeOffline.setPayType((byte) BizEnum.PaymentType.Wallet.getType());
			tradeOffline.setTransactionStatus((byte) BizEnum.TransactionStatus.Success.getType());
			tradeOffline.setTransOrderNo(payResult.getOrderId());
			tradeOffline.setPayOrderid(payBalanceChange.getOrgOrderNum());
			tradeOffline.setMemo("优惠券券码核销结算");
			int  result = tradeOfflineMapper.insertSelective(tradeOffline);
			//更新订单明细状态
			record.setLastOrderNum(payBalanceChange.getOrgOrderNum());
			record.setSuccessOrderId(tradeOffline.getId());
			record.setStatus(MerchantSettedStatus.merchantSetted.getType());
			merchantSettedRecordMapper.updateByPrimaryKey(record);
			result = couponUserMapper.updateShopSettingInfo(null,tradeOffline.getId(),settingShop.getDetailIds());

		}catch (Exception e) {
			logger.error("commit error", e);
			e.printStackTrace();
			throw e;
		}
		return 1;
	}


	//优惠券核销门店结算出款
	public int goodsShopOutMoney(ShopSettedBean settingShop,Date statisDate) throws Exception{
		if(settingShop == null)
			return 0;

		settingShop.setSettingPrice(settingShop.getSettingPrice()==null?0:settingShop.getSettingPrice());
		if(settingShop.getSettingPrice() <= 0)
			return 0;
		//将门店结算插入结算记录
		String OrgOrderNum = UtilFun.createOrderNum();
		MerchantSettedRecord record =merchantSettedRecordMapper.selectByShop(settingShop.getShopId(),settingShop.getGroupId(),MerchantSettedType.goodsSetted.getType(),DateUtils.getDateTimeString("yyyy-MM-dd", statisDate));
		if(record!=null){
			if(record.getStatus().intValue()==MerchantSettedStatus.merchantSetted.getType()){
				throw new Exception("该商户已经结算 请手动调整");
			}
		}else{
			record =new MerchantSettedRecord();
		}
		record.setAmount(settingShop.getSettingPrice());
		record.setGroupId(settingShop.getGroupId());
		String amountDes=SysUtils.string2MD5(record.getAmount() + SysUtils.formatString(settingShop.getShopId(), 7));
		record.setAmountDes(amountDes);
		record.setGmtCreate(new Date());
		record.setGmtModified(new Date());
		record.setLastOrderNum(OrgOrderNum);
		record.setOutOrderNum(OrgOrderNum);
		record.setShopId(settingShop.getShopId());
		record.setStaticDate(statisDate);
		record.setStatus(MerchantSettedStatus.merchantUnSetted.getType());
		record.setType(MerchantSettedType.goodsSetted.getType());
		if(record.getId()!=null&&record.getId()>0){
			merchantSettedRecordMapper.updateByPrimaryKey(record);
		}else{
			merchantSettedRecordMapper.insert(record);
		}

		int result = orderGoodItemMapper.updateShopSettingInfo(record.getId(),null,settingShop.getDetailIds());

		StringBuffer sb = new StringBuffer();
		Shop shop = shopMapper.selectByPrimaryKey(settingShop.getShopId());
		Group group = groupMapper.selectByPrimaryKey(settingShop.getGroupId());
		ShopGroupRelation shopGroupRelation = shopGroupRelationMapper.selectShopInfo(group.getId(),shop.getId());



		PayBalanceChange payBalanceChange = PayBalanceChange.initialize(group.getPayGroupCode(),
				shopGroupRelation.getPayMerchantCode(),settingShop.getSettingPrice().toString(), "1",
				OrgOrderNum, DateUtils.getDateTimeString("yyyyMMddHHmmss"), StringUtil.getRandNumberStr(10), "156");
		PayResult payResult = IPayAPI.consumptionBalanceChangeMerchant(payBalanceChange);
		if(payResult==null||!payResult.getRespCode().equals("0000")) {
			String newOrgOrderNum = UtilFun.createOrderNum();
			record.setOutOrderNum(newOrgOrderNum);
			record.setStatus(MerchantSettedStatus.merchantSettedFail.getType());
			merchantSettedRecordMapper.updateByPrimaryKey(record);
			logger.error(sb.append("商家:" + shop.getMerchantName() + "(" + settingShop.getShopId() + ")"  + "打款失败!"));
			return -1;
		}

		try {
			//交易记录创建
			TradeOffline tradeOffline = new TradeOffline();
			tradeOffline.setGmtCreate(new Date());
			tradeOffline.setGroupId(group.getId());
			tradeOffline.setOrderId(OrgOrderNum);
			tradeOffline.setPayerId(group.getId());
			tradeOffline.setPayerName(group.getMerchantName());
			tradeOffline.setPayerType((byte) CommonEnum.UserType.BusinessManager.getType());
			tradeOffline.setReceiverId(shop.getId().toString());
			tradeOffline.setReceiverName(shop.getMerchantName());
			tradeOffline.setReceiverType((byte) CommonEnum.UserType.Store.getType());
			tradeOffline.setTransactionType((byte) BizEnum.TransactionType.AddBalanceMerchant.getType());
			tradeOffline.setOrderAmount(settingShop.getSettingPrice());
			tradeOffline.setRealAmount(settingShop.getSettingPrice());
			tradeOffline.setSubType((byte) BizEnum.PaymentScene.Online.getType());
			tradeOffline.setIsWallet(true);
			tradeOffline.setPayType((byte) BizEnum.PaymentType.Wallet.getType());
			tradeOffline.setTransactionStatus((byte) BizEnum.TransactionStatus.Success.getType());
			tradeOffline.setTransOrderNo(payResult.getOrderId());
			tradeOffline.setPayOrderid(payBalanceChange.getOrgOrderNum());
			tradeOffline.setMemo("商城商品结算");
			result = tradeOfflineMapper.insertSelective(tradeOffline);
			//更新订单明细状态
			record.setLastOrderNum(payBalanceChange.getOrgOrderNum());
			record.setSuccessOrderId(tradeOffline.getId());
			record.setStatus(MerchantSettedStatus.merchantSetted.getType());
			merchantSettedRecordMapper.updateByPrimaryKey(record);
			result = orderGoodItemMapper.updateShopSettingInfo(null,tradeOffline.getId(),settingShop.getDetailIds());
		}catch (Exception e) {

			logger.error("commit error", e);
			e.printStackTrace();
			throw e;
		}
		return 1;
	}


	@Override
	public BaseOutDTO updateRebatewithdraw(TradeOffline tradeOffline, BigDecimal refundAmount,Long shopId) throws ApplicationException {
		Shop shop = new Shop();
		Group group = new Group();

	//	String newTradeOrderNum=tradeOffline.getTransOrderNo();
		String newTradeOrderNum=UtilFun.createOrderNum("RF");
		BaseOutDTO baseOutDTO=new BaseOutDTO();
		Date date = new Date();
		long tradeOfflineId = tradeOffline.getId();
		Member member =memberMapper.queryGroup(tradeOffline.getPayerId());
		if(member==null){
			baseOutDTO.setErrorCode(Rescode.FAIL, "会员信息不存在");
			return baseOutDTO;
		}
		String payGroupCode=member.getPayGroupCode();
		Long groupId=member.getGroupId();

		if(shopId !=null){
			shop = shopMapper.selectByPrimaryKey(shopId);
		}else{
			group = groupMapper.selectByPrimaryKey(groupId);
		}


		//原交易获的的优惠券退回
		couponUserMapper.refundUserCouponByTradeOfflineId(tradeOfflineId);
		//原交易获的的红包退回
		RedpackageUser redpackageUser = redpackageUserMapper.getRedPackageUserByTradeOfflineId(tradeOfflineId);
		if(redpackageUser != null) {
			if(redpackageUser.getGetStatus() == ActivityEnum.RedpackageGetStatus.Gotten.getType()) {
				TradeOffline tradeOffline2 = new TradeOffline();
				tradeOffline2.setGroupId(groupId);
				tradeOffline2.setOrderId(newTradeOrderNum);
				tradeOffline2.setIsWallet(true);
				tradeOffline2.setGmtCreate(date);
				tradeOffline2.setGmtModified(date);
//				tradeOffline2.setPayerId(tradeOffline.getPayerId());
				tradeOffline2.setPayerType(tradeOffline.getPayerType());
				tradeOffline2.setPayType((byte) BizEnum.PaymentType.Wallet.getType());
//				tradeOffline2.setPayerName(tradeOffline.getPayerName());

				if(shop !=null){
					tradeOffline2.setPayerId(tradeOffline.getPayerId());
					tradeOffline2.setPayerName(tradeOffline.getPayerName());
//					tradeOffline2.setPayerId(shopId);
//					tradeOffline2.setPayerName(shop.getMerchantName());
				}else{
					tradeOffline2.setPayerId(groupId);
					tradeOffline2.setPayerName(group.getMerchantName());
				}
				tradeOffline2.setRealAmount(-(redpackageUser.getRealAmount()));
				tradeOffline2.setOldOrderId(redpackageUser.getTradeOfflineId());
				tradeOffline2.setTransactionType((byte) BizEnum.TransactionType.AddBalance.getType());
				tradeOffline2.setTransactionStatus((byte) BizEnum.TransactionStatus.Success.getType());
				tradeOffline2.setMemo("用户已领取红包退回");
				String OrgOrderNum = UtilFun.createOrderNum();
				tradeOffline2.setPayOrderid(OrgOrderNum);
				PayBalanceChange payBalanceChange = PayBalanceChange.initialize(payGroupCode, member.getVirtualCard(), tradeOffline2.getRealAmount().toString(), "0", OrgOrderNum,
						DateUtils.getDateTimeString("yyyyMMddHHmmss"), UtilFun.createRandomNum(10), "156");

				tradeOfflineMapper.insertSelective(tradeOffline2);
				PayResult payResult=walletService.updateUserLockedAmount(member.getVirtualCard(), payGroupCode, member.getUserId(), "-"+tradeOffline2.getRealAmount(), "0", 0,newTradeOrderNum);
	               if(payResult==null){
	            	   throw new ApplicationException("用户已领取红包退回 处理失败");
	               }
			}
			redpackageUser.setGetStatus(ActivityEnum.RedpackageGetStatus.Refunded.getType());
			redpackageUserMapper.updateByPrimaryKeySelective(redpackageUser);
		}
		//原交易获的的积分退回
		BonusSendLog bonusSendLog = bonusSendLogMapper.getByOrderId(tradeOffline.getId());
		if(bonusSendLog != null) {
			Integer status = bonusSendLog.getAdjustStatus();
			bonusSendLog.setAdjustStatus(ActivityEnum.BonusSendStatus.TradeCancel.getType());
			int i = bonusSendLogMapper.updateByPrimaryKeySelective(bonusSendLog);
			if(i == 1) {
				Long memberId = member.getId();
				Integer bonusAmount = bonusSendLog.getAdjustAmount();
				if(status == ActivityEnum.BonusSendStatus.Freezing.getType()) {
					memberMapper.updateBonusFreezeById(memberId, -(bonusAmount));
				} else if(status == ActivityEnum.BonusSendStatus.Accounting.getType()) {
					memberMapper.updateBonusPreAcountById(memberId, -(bonusAmount));
				} else if(status == ActivityEnum.BonusSendStatus.Accounted.getType()) {
					memberMapper.deductionActualConsumeBonus(memberId, bonusAmount);
				} else {
					throw new ApplicationException("积分状态错误");
				}
			}
		}

		//原交易获的的返现退回
		//消费返现的交易记录
//		TradeOffline tradeOffline3 = tradeOfflineMapper.getTradeOfflineByRelatedTradeOfflineId(tradeOffline.getId());
		TradeOffline tradeOffline3 = tradeOfflineMapper.getTradeDataByRelatedTradeOfflineId(tradeOffline.getId(),member.getId().toString());
		if(tradeOffline3 != null) {
			tradeOffline3.setOrderAmount(-1*tradeOffline3.getOrderAmount());
			tradeOffline3.setRealAmount(-1*tradeOffline3.getRealAmount());
			tradeOffline3.setGmtModified(tradeOffline3.getGmtModified());
			tradeOffline3.setTransactionStatus((byte) BizEnum.TransactionStatus.ISRefund.getType());
			tradeOffline3.setPayType((byte) BizEnum.PaymentType.Wallet.getType());
			tradeOfflineMapper.updateByPrimaryKeySelective(tradeOffline3);

			 PayResult payResult=walletService.updateUserLockedAmount(member.getVirtualCard(), payGroupCode, member.getUserId(), tradeOffline3.getRealAmount()+"", "0", 0,tradeOffline3.getOrderId());
 		    if(payResult==null){
 		    	throw new ApplicationException("退款红包(或返现)处理失败");
 	        }  
		}


		Long oldTradeId=tradeOffline.getId();
		Integer point=tradeOffline.getBonusAmount();
		TradeOffline tradeOfflineNew = new TradeOffline();
		tradeOfflineNew.setGroupId(tradeOffline.getGroupId());
		tradeOfflineNew.setOrderId(newTradeOrderNum);
		tradeOfflineNew.setOldOrderId(tradeOffline.getId());
		tradeOfflineNew.setRealAmount(-(refundAmount).intValue());
		tradeOfflineNew.setOrderAmount(-(tradeOffline.getOrderAmount()));
		tradeOfflineNew.setBonusValue(-(tradeOffline.getBonusValue()));
		tradeOfflineNew.setBonusAmount(-(tradeOffline.getBonusAmount()));
		tradeOfflineNew.setTransOrderNo(null);
		tradeOfflineNew.setTransactionStatus((byte) BizEnum.TransactionStatus.Refund.getType());
		tradeOfflineNew.setPayType((byte) BizEnum.PaymentType.Wallet.getType());
		tradeOfflineNew.setTransactionType((byte) BizEnum.TransactionType.Refund.getType());
		tradeOfflineNew.setGmtCreate(date);
		tradeOfflineNew.setGmtModified(date);

		if(shop !=null){
			tradeOfflineNew.setPayerId(tradeOffline.getPayerId());
			tradeOfflineNew.setPayerName(tradeOffline.getPayerName());
//			tradeOfflineNew.setPayerId(shopId);
//			tradeOfflineNew.setPayerName(shop.getMerchantName());
		}else{
			tradeOfflineNew.setPayerId(groupId);
			tradeOfflineNew.setPayerName(group.getMerchantName());
		}


		tradeOfflineNew.setPayerType(tradeOffline.getPayerType());

		tradeOfflineNew.setReceiverId(shopId.toString());
		tradeOfflineNew.setReceiverName(shop.getMerchantName());
//		tradeOfflineNew.setReceiverId(tradeOffline.getPayerId().toString());
//		tradeOfflineNew.setReceiverName(tradeOffline.getPayerName());

		//购买劵 商城商品没有直接对应门店  暂不处理  门店总消费金额 退款次数
		//      shopUserMapper.addRefund(tradeOffline.getPayerId(), Long.parseLong(tradeOffline.getReceiverId()),tradeOffline.getRealAmount());
		tradeOfflineMapper.insertSelective(tradeOfflineNew);
		if(point > 0) {
			if(tradeOffline.getOrderId().startsWith(Const.CONSUMPTION_REAL)) {
				//商城商品时  积分核销记录订单id字段记录的是order_good表id
				OrderGood orderGood = orderGoodMapper.selectByOrderNo(tradeOffline.getOrderId());
				bonusVerifyLogMapper.updateStatusByOrderId(orderGood.getId(), ActivityEnum.BonusVerityStatus.TradeCancel.getType());
			} else {
				bonusVerifyLogMapper.updateStatusByOrderId(oldTradeId, ActivityEnum.BonusVerityStatus.TradeCancel.getType());
			}

			memberMapper.updateMemberBonusById(tradeOffline.getPayerId(), point);
		}

		baseOutDTO.setErrorCode(Rescode.SUCCESS, "退款成功");
		return baseOutDTO;

	}


	@Override
	public void updateOrderServiceGood(OrderInDTO orderInDTO) {
		//关闭订单
		OrderServiceGood orderServiceGood = new OrderServiceGood();
		orderServiceGood.setId(orderInDTO.getOrderId());
		orderServiceGood.setGmtModified(new Date());
		orderServiceGood.setOrderStatus(BizEnum.ServiceOrderStatus.Closed.getType());

		//先关闭交易订单记录
		/*TradeOffline tradeOffline = new TradeOffline();
		tradeOffline.setOrderId(orderInDTO.getOrderId().toString());
		tradeOffline.setTransactionStatus((byte) BizEnum.TransactionStatus.Cancel.getType());
		tradeOfflineMapper.updateByOrderIdSelective(tradeOffline);*/

		//修改优惠券状态，即解锁优惠券

		//再关闭服务商品订单
		orderServiceGoodMapper.updateByPrimaryKeySelective(orderServiceGood);

	}

	@Override
	public Response getServiceGoodOrderByGoodName(OrderServiceGood orderServiceGood) throws Exception {
		try {
			List<OrderServiceGood> orderServiceGoodList = orderServiceGoodMapper.getServiceGoodOrderByGoodName(orderServiceGood);
			if(orderServiceGoodList != null && orderServiceGoodList.size()>0){
                return Response.getSuccess(orderServiceGoodList);
            }else{
                return Response.getError("未查询到该商品的订单信息");
            }
		} catch (Exception e) {
			e.printStackTrace();
			return Response.getError("查询服务商品订单系统异常");
		}
	}


}
